package com.ra.order.rental;

import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import com.da.landlord.DaChargeBillRecord;
import com.da.landlord.DaChargeItem;
import com.da.landlord.DaRoom;
import com.googlecode.cswish.annotation.QLFormula;
import com.googlecode.cswish.annotation.cm;
import com.ra.coupon.UserCoupon;
import com.ra.landlord.FeeRecord;
import com.ra.landlord.LandlordOwnerUser;
import com.ra.landlord.Room;
import com.ra.landlord.TenantUser;
import com.ra.landlord.TransferRentalRecord;
import com.ra.pay.PaymentRecord;
import com.ra.util.DateTimeUtil;

/**
 * 租金订单
 * 
 * @author shen.kang Date: 2015-5-13
 *
 */
@Entity
public class RentalOrder {
	
	// 等待租客付款
	@cm("待付款")
	public static final int ORDER_STATE_WAITING_PAYMENT = 0;
	
	// 支付中
	@cm("支付中")
	public static final int ORDER_STATE_PAYING = 1;
	
	// 租客已付款，页面状态显示转账中
	@cm("已付款/待转帐")
	public static final int ORDER_STATE_PAYMENTED = 2;

	// 交租成功, 最终状态
	@cm("交租成功")
	public static final int ORDER_STATE_SUCCESS = 3;
	
	// 订单关闭, 作废的订单
	@cm("已关闭")
	public static final int ORDER_STATE_CLOSED = 4;
	
	@cm("订单类型：租金")
	public static final int ORDERTYPE_RENTAL = 1;
	
	@cm("订单类型：活动补贴")
	public static final int ORDERTYPE_ACTIVITY = 2;
	
	@cm("订单类型：手续费")
	public static final int ORDERTYPE_POUNDAGE = 3;
	
	public static BigDecimal ACTIVITY_AMOUNT = new BigDecimal(20.00);
	
	// 手续费比率
	public static BigDecimal POUNDAGE_RATE = new BigDecimal(0.015);
	
	// 非认证房东交租手续费率
	public static double POUNDAGE_AMOUNT_RATE = 0.015;
	
	public static String ACTIVITY_NAME = "2015百万活动";
	
	// 服务器异步通知页面路径
	public static final String NOTIFY_URL = "http://www.360fangxun.com/ra/order/rental/rentalOrder.requestResult.html";
	
	// 页面跳转同步通知页面路径
	public static final String RETURN_URL = "";
	
	// 支付中途中断跳转页面
	public static final String MERCHANT_URL = "http://127.0.0.1:8080/WS_WAP_PAYWAP-JAVA-UTF-8/xxxxxx.jsp";
	
	// 支付凭证小图分辨率
	public static final String RENTALVOUCHER_SMALL_IMAGE = "50x68";
	
	// 支付凭证大图分辨率
	public static final String RENTALVOUCHER_BIG_IMAGE = "500x600";
	
	private Integer id;
	
	@cm("房源")
	private Room room;
	
	@cm("Da房源")
	private DaRoom daRoom;
	
	private Integer roomType;

	// 商户订单号
	@cm("订单号")
	private String outTradeNo;
	
	// 订单创建时间
	@cm("创建时间")
	private Timestamp createTime;
	
	// 订单状态 0：待付款   1：支付中   2：待付款/已付款  3：交租成功   4：已关闭
	@cm("状态")
	private Integer orderState;
	
	// 支付记录
	@cm("支付记录")
	private PaymentRecord paymentRecord;
	
	// 订单描述
	@cm("描述")
	private String orderDec;
	
	// 商品展示URL
	private String showURL;
	
	// 创建用户
	private LandlordOwnerUser createUser;
	
	// 订单金额
	@cm("总金额")
	private BigDecimal totalFee;
	
	// 批量支付订单记录
	private BatchTransRentalRecord batchTransRentalRecord;
	
	// transient 订单状态展示
	private String orderStateShow;
	
	// 订单对应租客缴费记录
	private FeeRecord feeRecord;
	
	// 订单名称
	@cm("订单名称")
	private String orderName;
	
	// @Transient 
	private String strCreateTime; 
	
	@cm("交租凭证文件名称")
	private String rentalVoucherFileName;
	
	// transient
	@cm("交租凭证文件")
	@JsonIgnore
	private File rentalVoucher;
	
	// 交租凭证----支付方式
	// 0、微信支付 1、现金支付  2、网银支付  3、支付宝
	private Integer rentalVoucherPayType;
	
	// 微信支付ID
	private String prepayId;
	
	// 交租凭证缩略图
	private String smallImgPath;
	
	// 交租凭证放大图
	private String bigImgPath;
	
	// 订单手续费，1、支付之前手续费为0，支付完成之后计算手续费，并更新
	@cm("手续费")
	private BigDecimal procedureFee;
	
	private List<DaChargeItem> chargeItems;
	
	private DaChargeBillRecord chargeBillRecord;		//da待收账单
	
	// 待转账租金订单记录
	private TransferRentalRecord transferRentalRecord;
	
	// 交租途径1：HHZ平台支付 0：非HHZ平台支付
	private Boolean hhzPay;
	
	// 1：租金订单；2：活动补贴订单
	@cm("订单类型")
	private Integer orderType;
	
	// 优惠券
	private List<UserCoupon> userCoupons;
	
	// 应付总额
	private BigDecimal amountFee;
	
	// 租客
	private TenantUser tenantUser;
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "tenantUserId")
	@NotFound(action = NotFoundAction.IGNORE)
	public TenantUser getTenantUser() {
		return tenantUser;
	}

	public void setTenantUser(TenantUser tenantUser) {
		this.tenantUser = tenantUser;
	}
	
	public BigDecimal getAmountFee() {
		return amountFee;
	}

	public void setAmountFee(BigDecimal amountFee) {
		this.amountFee = amountFee;
	}

	@OneToMany(mappedBy="rentalOrder", cascade=CascadeType.PERSIST, orphanRemoval=true,
			fetch=FetchType.LAZY, targetEntity=UserCoupon.class)
	public List<UserCoupon> getUserCoupons() {
		return userCoupons;
	}

	public void setUserCoupons(List<UserCoupon> userCoupons) {
		this.userCoupons = userCoupons;
	}
	
	public Integer getOrderType() {
		return orderType;
	}

	public void setOrderType(Integer orderType) {
		this.orderType = orderType;
	}

	public Boolean getHhzPay() {
		return hhzPay;
	}

	public void setHhzPay(Boolean hhzPay) {
		this.hhzPay = hhzPay;
	}
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "transferRentalRecordId")
	public TransferRentalRecord getTransferRentalRecord() {
		return transferRentalRecord;
	}

	public void setTransferRentalRecord(TransferRentalRecord transferRentalRecord) {
		this.transferRentalRecord = transferRentalRecord;
	}
	@Transient
	public String getBigImgPath() {
		return bigImgPath;
	}

	public void setBigImgPath(String bigImgPath) {
		this.bigImgPath = bigImgPath;
	}

	@Transient
	public String getSmallImgPath() {
		return smallImgPath;
	}

	public void setSmallImgPath(String smallImgPath) {
		this.smallImgPath = smallImgPath;
	}

	public Integer getRentalVoucherPayType() {
		return rentalVoucherPayType;
	}

	public void setRentalVoucherPayType(Integer rentalVoucherPayType) {
		this.rentalVoucherPayType = rentalVoucherPayType;
	}

	public String getRentalVoucherFileName() {
		return rentalVoucherFileName;
	}

	public void setRentalVoucherFileName(String rentalVoucherFileName) {
		this.rentalVoucherFileName = rentalVoucherFileName;
	}

	@Transient
	public File getRentalVoucher() {
		return rentalVoucher;
	}

	public void setRentalVoucher(File rentalVoucher) {
		this.rentalVoucher = rentalVoucher;
	}

	@Transient
	public String getStrCreateTime() {
		strCreateTime = DateTimeUtil.formatDateTime(this.createTime, DateTimeUtil.ISO_DATETIME_FORMAT);
		return strCreateTime;
	}

	public void setStrCreateTime(String strCreateTime) {
		this.strCreateTime = strCreateTime;
	}

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Timestamp getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Timestamp createTime) {
		this.createTime = createTime;
	}

	public Integer getOrderState() {
		return orderState;
	}

	public void setOrderState(Integer orderState) {
		this.orderState = orderState;
	}

	@ManyToOne(cascade = {CascadeType.ALL}, fetch=FetchType.LAZY, optional=true)
	@LazyToOne(LazyToOneOption.PROXY)
	public PaymentRecord getPaymentRecord() {
		return paymentRecord;
	}

	public void setPaymentRecord(PaymentRecord paymentRecord) {
		this.paymentRecord = paymentRecord;
	}

	public String getOrderDec() {
		return orderDec;
	}

	public void setOrderDec(String orderDec) {
		this.orderDec = orderDec;
	}

	@Transient
	public String getShowURL() {
		return showURL;
	}

	public void setShowURL(String showURL) {
		this.showURL = showURL;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="createUserId")
	@Index(name="idx_ra_room_createuserid")
	public LandlordOwnerUser getCreateUser() {
		return createUser;
	}

	public void setCreateUser(LandlordOwnerUser createUser) {
		this.createUser = createUser;
	}

	public String getOutTradeNo() {
		return outTradeNo;
	}

	public void setOutTradeNo(String outTradeNo) {
		this.outTradeNo = outTradeNo;
	}

	public BigDecimal getTotalFee() {
		return totalFee;
	}

	public void setTotalFee(BigDecimal totalFee) {
		this.totalFee = totalFee;
	}

	@ManyToOne(fetch=FetchType.LAZY, cascade = CascadeType.PERSIST)
	@JoinColumn(name = "batchTransRentalRecordId")
	public BatchTransRentalRecord getBatchTransRentalRecord() {
		return batchTransRentalRecord;
	}

	public void setBatchTransRentalRecord(
			BatchTransRentalRecord batchTransRentalRecord) {
		this.batchTransRentalRecord = batchTransRentalRecord;
	}

	@Transient
	public String getOrderStateShow() {
		return orderStateShow;
	}

	public void setOrderStateShow(String orderStateShow) {
		this.orderStateShow = orderStateShow;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@NotFound(action = NotFoundAction.IGNORE)
	public FeeRecord getFeeRecord() {
		return feeRecord;
	}

	public void setFeeRecord(FeeRecord feeRecord) {
		this.feeRecord = feeRecord;
	}

	public String getOrderName() {
		return orderName;
	}

	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "roomId")
	@NotFound(action = NotFoundAction.IGNORE)
	public Room getRoom() {
		return room;
	}

	public void setRoom(Room room) {
		this.room = room;
	}
	
	@Transient
	@QLFormula(isColumn=true, value="room")
	public Object getOrderRoom() {
		if (this.room != null) {
			return this.room;
		} else {
			return this.daRoom;
		}
	}

	public String getPrepayId() {
		return prepayId;
	}

	public void setPrepayId(String prepayId) {
		this.prepayId = prepayId;
	}

	@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
	@NotFound(action = NotFoundAction.IGNORE)
	public DaRoom getDaRoom() {
		return daRoom;
	}

	public void setDaRoom(DaRoom daRoom) {
		this.daRoom = daRoom;
	}
	
	public Integer getRoomType() {
		return roomType;
	}

	public void setRoomType(Integer roomType) {
		this.roomType = roomType;
	}

	@OneToMany(fetch = FetchType.LAZY,cascade={CascadeType.MERGE})
	@JoinColumn(name="rentorder_id")
	public List<DaChargeItem> getChargeItems() {
		return chargeItems;
	}

	public void setChargeItems(List<DaChargeItem> chargeItems) {
		this.chargeItems = chargeItems;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	public DaChargeBillRecord getChargeBillRecord() {
		return chargeBillRecord;
	}

	public void setChargeBillRecord(DaChargeBillRecord chargeBillRecord) {
		this.chargeBillRecord = chargeBillRecord;
	}
	
}
